<template>
  <div>
    <Card title="双因素认证" class="w-1/2 !m-10px min-w-700px">
      <Card title="可用选项">
        <Collapse expandIconPosition="right" v-model:activeKey="availableKey">
          <!-- 验证app -->
          <CollapsePanel key="TOTP" :forceRender="true">
            <template #header>
              <div @click.stop>
                <Switch v-model:checked="isTOTP" @click="edit" />
              </div>
              <span class="mx-12px">验证APP</span>
            </template>
            <BasicForm @register="registerTOTPForm" />
          </CollapsePanel>
          <!-- SMS -->
          <CollapsePanel key="SMS" :forceRender="true">
            <template #header>
              <div @click.stop>
                <Switch v-model:checked="isSMS" @click="edit" />
              </div>
              <span class="mx-12px">SMS</span>
            </template>
            <BasicForm @register="registerSMSForm" />
          </CollapsePanel>
          <!-- 电子邮件 -->
          <CollapsePanel key="EMAIL" :forceRender="true">
            <template #header>
              <div @click.stop>
                <Switch v-model:checked="isEMAIL" @click="edit" />
              </div>
              <span class="mx-12px">电子邮件</span>
            </template>
            <BasicForm @register="registerEMAILForm" />
          </CollapsePanel>
          <!-- 备份验证码 -->
          <CollapsePanel key="BACKUP" :forceRender="true">
            <template #header>
              <div @click.stop>
                <Switch
                  v-model:checked="isBackUP"
                  :disabled="!(isTOTP || isSMS || isEMAIL)"
                  @click="edit"
                />
              </div>
              <span class="mx-12px">备份验证码</span>
            </template>
            <BasicForm @register="registerBackUPForm" />
          </CollapsePanel>
        </Collapse>
      </Card>
      <Card title="验证限制" class="!mt-12px">
        <BasicForm @register="registerJverifyForm" />
        <Collapse expandIconPosition="right" v-model:activeKey="verifyKey">
          <CollapsePanel key="LIMIT" :forceRender="true">
            <template #header>
              <div @click.stop>
                <Switch v-model:checked="isCheckLimit" @click="edit" />
              </div>
              <span class="mx-12px">验证码检查速率限制</span>
            </template>
            <BasicForm @register="registerCheckLimitForm" />
          </CollapsePanel>
        </Collapse>
      </Card>
      <Button type="primary" class="float-right my-24px" @click="save" :disabled="!isEdit">
        保存</Button
      >
    </Card>
  </div>
</template>

<script lang="ts" setup>
  import { Card, Collapse, CollapsePanel, Switch, Button } from 'ant-design-vue';
  import { BasicForm, useForm } from '/@/components/Form';
  import {
    JverifyForm,
    CheckLimitForm,
    TOTPForm,
    SMSForm,
    BackUPForm,
    EMAILForm,
    isEdit,
  } from './twoFactor.data';
  import { modalFormStyleSetting } from '/@/settings/thingsBoardDesign';
  import { get2faSetting, post2faSetting } from '/@/api/thingsborad/security/2fa/2fa';
  import { onMounted, ref, watch, watchEffect } from 'vue';
  import { useSystemStatusStoreWithOut } from '/@/store/modules/thingsboard/systemStatus';
  //验证码检查速率限制
  let isCheckLimit = ref<boolean>(false);
  let isTOTP = ref<boolean>(false);
  let isSMS = ref<boolean>(false);
  let isEMAIL = ref<boolean>(false);
  let isBackUP = ref<boolean>(false);
  //可用选项折叠面板key
  let availableKey = ref<Array<string>>([]);
  //控制验证码检查速率限制折叠面板key
  let verifyKey = ref<Array<string>>([]);
  onMounted(async () => {
    let res: Recordable = {};
    try {
      res = await get2faSetting();
    } catch (e) {}
    await setJverifyFieldsValue(res);
    if (res.verificationCodeCheckRateLimit) {
      isCheckLimit.value = true;
      let data = res.verificationCodeCheckRateLimit.split(':');
      await setCheckLimitFieldsValue({
        tryTimes: data[0],
        inTimes: data[1],
      });
    } else {
      isCheckLimit.value = false;
    }
    if (res.providers) {
      for (const item of res.providers) {
        if (item.providerType === 'TOTP') {
          isTOTP.value = true;
          await setTOTPFieldsValue(item);
        }
        if (item.providerType === 'SMS') {
          isSMS.value = true;
          await setSMSFieldsValue(item);
        }
        if (item.providerType === 'EMAIL') {
          isEMAIL.value = true;
          await setEMAILFieldsValue(item);
        }
        if (item.providerType === 'BACKUP_CODE') {
          isBackUP.value = true;
          await setBackUPFieldsValue(item);
        }
      }
    }
    isEdit.value = false;
  });

  // 验证APP
  const [
    registerTOTPForm,
    { setProps: setTOTPFormProps, setFieldsValue: setTOTPFieldsValue, validate: validateTOTPForm },
  ] = useForm({
    layout: 'vertical',
    schemas: TOTPForm,
    showActionButtonGroup: false,
    disabled: true,
    ...modalFormStyleSetting,
  });
  // SMS
  const [
    registerSMSForm,
    { setProps: setSMSFormProps, setFieldsValue: setSMSFieldsValue, validate: validateSMSForm },
  ] = useForm({
    layout: 'vertical',
    schemas: SMSForm,
    showActionButtonGroup: false,
    disabled: true,
    ...modalFormStyleSetting,
  });
  // 电子邮件
  const [
    registerEMAILForm,
    {
      setProps: setEMAILFormProps,
      setFieldsValue: setEMAILFieldsValue,
      validate: validateEMAILForm,
    },
  ] = useForm({
    layout: 'vertical',
    schemas: EMAILForm,
    showActionButtonGroup: false,
    disabled: true,
    ...modalFormStyleSetting,
  });
  // 备份验证码
  const [
    registerBackUPForm,
    {
      setProps: setBackUPFormProps,
      setFieldsValue: setBackUPFieldsValue,
      validate: validateBackUPForm,
    },
  ] = useForm({
    layout: 'vertical',
    schemas: BackUPForm,
    showActionButtonGroup: false,
    disabled: true,
    ...modalFormStyleSetting,
  });
  // 验证限制
  const [
    registerJverifyForm,
    { validate: validateJverifyForm, setFieldsValue: setJverifyFieldsValue },
  ] = useForm({
    layout: 'vertical',
    schemas: JverifyForm,
    showActionButtonGroup: false,
    ...modalFormStyleSetting,
  });
  // 验证码查询速率限制
  const [
    registerCheckLimitForm,
    {
      setProps: setCheckLimitProps,
      setFieldsValue: setCheckLimitFieldsValue,
      validate: validateCheckLimitForm,
    },
  ] = useForm({
    layout: 'vertical',
    schemas: CheckLimitForm,
    showActionButtonGroup: false,
    disabled: true,
    ...modalFormStyleSetting,
  });
  watch(
    () => isTOTP.value,
    (nVal) => {
      if (nVal) {
        availableKey.value.push('TOTP');
        setTOTPFormProps({ disabled: false });
      } else {
        let index = availableKey.value.indexOf('TOTP');
        if (index !== -1) {
          availableKey.value.splice(index, 1);
        }
        setTOTPFormProps({ disabled: true });
      }
    },
  );
  watch(
    () => isSMS.value,
    (nVal) => {
      if (nVal) {
        availableKey.value.push('SMS');
        setSMSFormProps({ disabled: false });
      } else {
        let index = availableKey.value.indexOf('SMS');
        if (index !== -1) {
          availableKey.value.splice(index, 1);
          setSMSFormProps({ disabled: true });
        }
      }
    },
  );
  watch(
    () => isEMAIL.value,
    (nVal) => {
      if (nVal) {
        availableKey.value.push('EMAIL');
        setEMAILFormProps({ disabled: false });
      } else {
        let index = availableKey.value.indexOf('EMAIL');
        if (index !== -1) {
          availableKey.value.splice(index, 1);
          setEMAILFormProps({ disabled: true });
        }
      }
    },
  );
  watch(
    () => isBackUP.value,
    (nVal) => {
      if (nVal) {
        availableKey.value.push('BACKUP');
        setBackUPFormProps({ disabled: false });
      } else {
        let index = availableKey.value.indexOf('BACKUP');
        if (index !== -1) {
          availableKey.value.splice(index, 1);
        }
        setBackUPFormProps({ disabled: true });
      }
    },
  );
  watch(
    () => isCheckLimit.value,
    (nVal) => {
      if (nVal) {
        verifyKey.value.push('LIMIT');
        setCheckLimitProps({ disabled: false });
      } else {
        verifyKey.value = [];
        setCheckLimitProps({ disabled: true });
      }
    },
  );
  watchEffect(() => {
    if (!(isTOTP.value || isSMS.value || isEMAIL.value)) {
      isBackUP.value = false;
    }
  });
  function edit() {
    isEdit.value = true;
  }
  const useStore = useSystemStatusStoreWithOut();
  watch(
    () => isEdit.value,
    (nVal) => {
      useStore.setIsDataChanged(nVal);
    },
    {
      immediate: true,
    },
  );
  const save = async () => {
    let data = await validateJverifyForm();
    if (isCheckLimit.value) {
      let res = await validateCheckLimitForm();
      data.verificationCodeCheckRateLimit = res.tryTimes + ':' + res.inTimes;
    }
    data.providers = [];
    if (isTOTP.value) {
      let res = await validateTOTPForm();
      res = { ...res, providerType: 'TOTP' };
      data.providers.push(res);
    }
    if (isSMS.value) {
      let res = await validateSMSForm();
      res = { ...res, providerType: 'SMS' };
      data.providers.push(res);
    }
    if (isEMAIL.value) {
      let res = await validateEMAILForm();
      res = { ...res, providerType: 'EMAIL' };
      data.providers.push(res);
    }
    if (isBackUP.value) {
      let res = await validateBackUPForm();
      res = { ...res, providerType: 'BACKUP_CODE' };
      data.providers.push(res);
    }

    try {
      await post2faSetting(data);
    } catch (e) {}
    isEdit.value = false;
  };
</script>
